Loading...
 

Explanation of Drag and Drop

Explanation of Drag and Drop

Drag and Drop offers the possibility to interactively change entries and especially relations of the window objects on the surface without explicitly executing InstantView® code.
In effect, a drag and drop action is similar to the execution of OboxFill, whereby the selection is automatic and when released (drop) is equal to the object under the mouse cursor.

A drag and drop action is started (drag) by pressing and holding down the left mouse button on an object, i.e. on a widget representing a part(s) of an object(s) or on an element to an object within an ObjectBox. Afterwards, the mouse cursor can be moved across the screen while holding down the left mouse button, which is visualised by a changed shape of the cursor. The action (drop) is finished by releasing the left mouse button anywhere on the screen. If the mouse cursor did not have the form Cancel (see below) at this time, the object under the cursor was allowed for the action and the action linked to the drag and drop was carried out.

These 3 stages of drag and drop described above: start, movement, end, are essential for the whole process. They can be influenced in detail, i.e. there are certain messages (events) which are sent out by the system during a stage. Depending on how an InstantView® implementation reacts to them, a certain behaviour of the system occurs:

Start(Drag):
Here, the system initially only visualises the drag and drop: the mouse cursor takes the form of a drag and drop cursor, as it is set in the movement stage (see there). In addition, some ObjectBoxes generate an image that represents the dragged object and moves with the mouse cursor.

movement:
At this stage, the system must decide whether immediate release (drop) leads to an acceptable result. This is done in two ways: Firstly, for logical reasons, constellations arise which are not permitted for a successful drop. Of course, there must be a widget below the mouse cursor that can display the dragged object. A drop on an empty window is therefore always prohibited. Furthermore, there are structural reasons which in some cases would lead to absurd results in case of a successful drop. For example, the ObjectTree automatically prohibits the dropping of an object into one of its subordinated objects. Such an action would otherwise result in an endless recursion of fillings.

As a second option, you can decide in the InstantView® code whether the drop actions, which seem to be correct for purely logical reasons, are also correct for semantic reasons, or even desired. For this purpose, the system sends the following message to some widgets exactly when the partners involved (source (drag) object, target (drop) object, insert mode) have changed. The syntax is:

IS_DROPPABLE:

Stack
Stack Position Description
Stack(In) Top ]
Top 1 Source object On (drag)
... ...
Top-n Source object O1 (drag)
Top n-1 [
Top n-2 Target object (drop) or NULL
Top n-3 Insert mode (integer, see below)
Stack(Out) 0 or 1

Only widgets with multiple selection option (ObjectList,ObjectListView) as source widget can pass multiple source objects. However, a list (i.e. the markers '[' and ']') is always passed. Only one object can be used as target object. (Object under the cursor is selected, not the selected ones!) The insert mode is a number whose meaning is explained below.

If you want to influence the drag and drop behaviour, you define a label IS_DROPPABLE with the following InstantView® code in the same way as for all other system events. Based on the parameters found on the stack, it decides whether, for example, the source object fits into a collection of the target object, i.e. whether it would be a suitable subordinate object. If this is the case, the InstantView® code implementing IS_DROPPABLE should leave the value 1 on the stack (as return value) after execution, otherwise it should leave the value 0 accordingly.

The insertion modes in numerical values and cursor shapes (which can change when the cursors are individually changed in Windows), which have already been mentioned several times up to this point, are as follows

Cursor Name Mode Description
 DragCopM.gif (950 byte) Cancel 1 With this value IS_DROPPABLE would not be called at all. (Drop already logically not possible).
 DragCopM.gif (950 byte) Move 0 An object is moved, i.e. the reference at the source is removed
 DragCopy.gif (933 Byte) Copy 2 An object is copied, i.e. another reference is inserted at the destination
 DragCopM.gif (950 byte) Move+Sibling 4 An object is moved and at the same time sorted into a specific position at the target.
 DragCopM.gif (950 byte) Copy+Sibling 6 An object is copied and at the same time sorted to a specific location at the destination.
 DragCopM.gif (950 byte) Multiple Move 8 Multiple objects are moved
 dragcopm.gif (950 Byte) multiple copy 10 Multiple objects are copied

The insertion modes are determined by various factors. With the - and -key to select between Copy and Move. In some cases only Move is logically not possible (object cannot be removed), in this case the message "Move" appears at -key to select the Move mode, the Cancel cursor is displayed, while -key and Copy the copy cursor appears. Without keys there are default behaviours such that within a widget (e.g. moving in a list) automatically Move, between 2 different widgets automatically Copy is selected.
Sibling mode is activated without pressing any key or with only - and/or -key is pressed, determined by the position of the cursor relative to objects. Between 2 objects (or very close to the edge of an object display) the system automatically switches to sibling mode. If (additionally) the -key is held down, the sibling mode is always attempted. The position selected is the edge of an object display that is closest to the mouse cursor position. In the lower half of an only half filled ObjectTree this is e.g. always the lower edge of the last displayed object. If the drop is executed in this example, the new object becomes the new lowest object with the same parent object as the previous lowest object.
Sibling mode may also be inadmissible, regardless of the admissibility of a normal drop. (FOR EXAMPLE: Mixing of elements from 2 different collections in the ObjectTree) In this case either the Cancel-Cursor appears or the normal mode is selected automatically. (The latter never happens when the -key).
Multiple modes are always selected if several objects were selected in the source widget(ObjectList,ObjectListView). In this case, all these selected objects are moved. Sibling cannot be inserted in multiple mode.

End(Drop):
Before the following actions are performed, make sure that IS_DROPPABLE is executed again in any case. Before inserting a candidate, it is therefore checked once again.

In direct response to the release of the mouse button, the machine sends the event

DROP:

Stack
Stack Position Description
Stack(In) Top ]
Top 1 Source Object On (Drag)
......
Top-nSource object O1 (drag)
Top-n-1[
Top-n-2Target object (drop) or NULL
Top-n-3 Insert mode
Stack(Out) -

to the target widget.

It is up to the writer of the InstantView® code reacting to this event to decide whether and in what form to react to a drop.
"If" here means that the entire reaction can also be aborted with cancel. There is also the possibility of an error abort, e.g. due to an error message from the system. In this case the result of an intentional abort is equal to cancel.
Termination in case of unintentional action is generally necessary, as further automatic reactions are associated with the successful completion of the drag and drop. For example, the source reference is deleted with Move in the insert modes described above.
The insert mode is also passed for a more detailed response, but cannot be overwritten. So during sibling (sorted) insertion the desired position is internally noted and evaluated with the transferred source object during subsequent actions such as OboxFill. Although it is possible to implement a reaction that does not correspond to the insert mode by specific manipulations, this should be avoided, as this will definitely confuse the user and lead to wrong assumptions.

Since insert modes with Copy and generally drops from other widgets for an ObjectBox than target widgets like FillObox lead to an increase of contained elements, the restrictions defined by SetLimit and SetLevels apply as with these commands. Especially when copying in the ObjectTree, there is the possibility that a cyclic structure is created by such an action, even if it is not possible to move a parent object directly into a child object. In this case, as described for the ObjectTree, a corresponding virtual element is generated, with which the cycle is broken.

If the subordinate objects of the target object have not yet been read in (by SetLevels to a value less than or equal to the level of the target object; cannot occur with Sibling), they are automatically read in if the drop is successful. It is therefore ensured (just as with OboxFill) that subordinate objects are always read in completely or not at all.